package com.yitao.cms.service.order;

import com.skipper.base.data.querydsl.PredicateBuilder;
import com.skipper.base.json.JSON;
import com.skipper.base.json.JSONArray;
import com.skipper.base.json.JSONObject;
import com.skipper.base.service.GenericEntityService;
import com.yitao.client.dto.expressage.OrderLogisticTaskDto;
import com.yitao.client.model.expressage.LogisticDetailModel;
import com.yitao.client.model.expressage.LogisticHeadModel;
import com.yitao.client.model.expressage.OrderLogisticTaskModel;
import com.yitao.client.model.expressage.QOrderLogisticTaskModel;
import com.yitao.client.model.order.MallOrderDeliveryModel;
import com.yitao.cms.constant.intergenix.IntergenixConstant;
import com.yitao.cms.service.expressage.LogisticDetailService;
import com.yitao.cms.service.expressage.LogisticHeadService;
import com.yitao.cms.utils.BaseUtils;
import com.yitao.cms.utils.DateUtils;
import com.yitao.cms.vo.expressage.KuaiDi100DetailVo;
import com.yitao.cms.vo.expressage.KuaiDi100Vo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.*;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class CmsOrderLogisticaskService extends GenericEntityService<OrderLogisticTaskModel, OrderLogisticTaskDto, QOrderLogisticTaskModel> {
    private BaseUtils base = BaseUtils.getInstance();

    @Autowired
    private LogisticHeadService logisticHeadService;
    @Autowired
    private LogisticDetailService logisticDetailService;

    public CmsOrderLogisticaskService(EntityManager entityManager) {
        super(entityManager);
    }

    @Transactional
    public void save(OrderLogisticTaskModel orderLogisticTaskModel) {
        repository.save(orderLogisticTaskModel);
    }

    public List<OrderLogisticTaskModel> getOrderLogisticTaskModelByLogisticCodeAndLogisticNumber(MallOrderDeliveryModel mallOrderDeliveryModel) {
        return queryFactory.select(Q).from(Q).where(Q.logisticCode.eq(mallOrderDeliveryModel.getDeliveryCompanyCode()).and(Q.logisticNumber.eq(mallOrderDeliveryModel.getDeliveryNo()))).fetch();
    }

    /**
     * 功能描述: 新增一条不重复的数据(180天)
     *
     * @param logisticCode
     * @param logisticName
     * @param logisticNumber
     *
     * @return
     * @auther Kien
     * @date 2019/12/5 14:29
     */
    @Transactional
    public JSONObject saveLogistic(String logisticCode, String logisticName, String logisticNumber) {
        JSONObject jsonObject = new JSONObject();
        if(base.parametersIsBlank(logisticCode, logisticName, logisticNumber)) {
            jsonObject.put("status", IntergenixConstant.JsonEnmu.ERROR.getStatus()); // 失败
            logger.info("物流单号或者物流商名称或物流编码为空,logisticCode->:" + logisticCode + " logisticName->:" + logisticName + " logisticNumber->:" + logisticNumber);
            return jsonObject;
        }
        // 判断这个物流单号是否存在，
        Date date = new Date();
        Date beforeDate = DateUtils.getPastDate(180); // 180天前的日期
        List<OrderLogisticTaskModel> all = repository.findAll(PredicateBuilder.conjunction()
                .and(() -> Q.createTime.between(beforeDate, date)) // 只获取180天前到今天是否有该物流信息
                .and(() -> Q.logisticNumber.eq(logisticNumber))
                .and(() -> Q.logisticCode.eq(logisticCode))
                .get());
        if(all != null && all.size() != 0) { // 已经加入到任务中，直接返回成功
            logger.info("180天内存在这个物流单号信息，不需要添加");
            jsonObject.put("status", IntergenixConstant.JsonEnmu.PARAM_NULL.getStatus()); // 成功
            return jsonObject;
        }
        OrderLogisticTaskModel orderLogisticTaskModel = new OrderLogisticTaskModel();
        orderLogisticTaskModel.setLogisticCode(logisticCode.trim());
        orderLogisticTaskModel.setLogisticName(logisticName.trim());
        orderLogisticTaskModel.setLogisticNumber(logisticNumber.trim());
        orderLogisticTaskModel.setIsClose(false);
        orderLogisticTaskModel.setCreateBy(-10L); // -10表示供应链项目单号
        orderLogisticTaskModel.setCreateTime(date);
        repository.save(orderLogisticTaskModel);
        jsonObject.put("status", IntergenixConstant.JsonEnmu.SUCCESS.getStatus()); // 成功
        return jsonObject;
    }

    /**
     * 功能描述: 获取指定物流单号的物流信息
     *
     * @param result 物流单号列表
     *
     * @return
     * @auther Kien
     * @date 2019/12/9 10:46
     */
    public JSONObject getLogisticDetail(String result) {
        logger.info("开始获取物流信息");
        logger.info("请求参数为: " + result);
        JSONObject jsonObject = new JSONObject();
        if(StringUtils.isEmpty(result)) {
            logger.info("物流单号列表为空");
            jsonObject.put("status", IntergenixConstant.JsonEnmu.PARAM_NULL.getStatus());
            return jsonObject;
        }
        List<OrderLogisticTaskDto> list = JSON.parseArray(result, OrderLogisticTaskDto.class);
        if(CollectionUtils.isEmpty(list)){
            logger.info("物流单号列表为空");
            jsonObject.put("status", IntergenixConstant.JsonEnmu.PARAM_NULL.getStatus());
            return jsonObject;
        }
        List<KuaiDi100Vo> resultList = new ArrayList<>();
        for(OrderLogisticTaskDto orderLogisticTaskModel: list) {
            String logisticCode = orderLogisticTaskModel.getLogisticCode(); // 物流编码
            String logisticNumber = orderLogisticTaskModel.getLogisticNumber(); // 物流单号
            String logisticName = orderLogisticTaskModel.getLogisticName(); // 物流名称
            if(!base.parametersIsBlank(logisticCode, logisticNumber)){
                LogisticHeadModel logisticHead = logisticHeadService.findLogisticHeadByCodeAndNumber(logisticCode, logisticNumber);
                List<LogisticDetailModel> logisticDetailList = new ArrayList<>();
                if(logisticHead != null) {
                    logisticDetailList = logisticDetailService.findLogistaicDetailByTrackingId(logisticHead.getId());
                }
                if(!CollectionUtils.isEmpty(logisticDetailList)) {
                    KuaiDi100Vo kuaiDi100Vo = new KuaiDi100Vo();
                    // 物流公司单号
                    kuaiDi100Vo.setNu(orderLogisticTaskModel.getLogisticNumber());
                    // 物流公司编码
                    kuaiDi100Vo.setCom(orderLogisticTaskModel.getLogisticCode());
                    // 物流公司名称，这里用message保存
                    kuaiDi100Vo.setMessage(logisticName);
                    List<KuaiDi100DetailVo> detailList = new ArrayList<>();
                    for(LogisticDetailModel logisticDetailModel: logisticDetailList){
                        KuaiDi100DetailVo kuaiDi100DetailVo = new KuaiDi100DetailVo();
                        kuaiDi100DetailVo.setFtime(DateUtils.getDateSecondFormat(logisticDetailModel.getTrackingTime()));
                        kuaiDi100DetailVo.setContext(logisticDetailModel.getTrackingDesc());
                        detailList.add(kuaiDi100DetailVo);
                    }
                    logger.info("保存爬取物流信息");
                    kuaiDi100Vo.setData(detailList);
                    resultList.add(kuaiDi100Vo);
                }
            }
        }
        logger.info("获取物流信息完成，返回");
        jsonObject.put("status", IntergenixConstant.JsonEnmu.SUCCESS.getStatus());
        jsonObject.put("result", resultList);
        return jsonObject;
    }

    /**
     * 功能描述: 关闭指定物流单号信息爬取
     *
     * @param result 需要关闭的物流信息列表
     *
     * @return
     * @auther Kien
     * @date 2019/12/9 11:58
     */
    @Transactional
    public JSONObject closeLogisticTask(String result) {
        List<OrderLogisticTaskDto> list = JSON.parseArray(result, OrderLogisticTaskDto.class);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("status", IntergenixConstant.JsonEnmu.ERROR.getStatus());
        if(CollectionUtils.isEmpty(list)) {
            jsonObject.put("status", IntergenixConstant.JsonEnmu.PARAM_NULL.getStatus());
            return jsonObject;
        }
        List<Long> ids = new ArrayList<>();
        for(OrderLogisticTaskDto orderLogisticTaskModel: list){
            List<OrderLogisticTaskModel> all = repository.findAll(PredicateBuilder.conjunction()
                    .and(() -> Q.logisticCode.eq(orderLogisticTaskModel.getLogisticCode()))
                    .and(() -> Q.logisticNumber.eq(orderLogisticTaskModel.getLogisticNumber())).get());
            if(!CollectionUtils.isEmpty(all)) {
                List<Long> idList = all.stream().map(e -> e.getId()).collect(Collectors.toList());
                ids.addAll(idList);
            }
        }
        int i = updateIsCloseByWaiTingSignTime(ids);
        if(i == 0) {
            return jsonObject;
        } else {
            jsonObject.put("status", IntergenixConstant.JsonEnmu.SUCCESS.getStatus());
        }
        return jsonObject;
    }

    /**
     *
     * 功能描述: 修改物流轨迹是否完结标识
     *
     * @param ids id列表
     * @return
     * @auther: Kien
     * @date: 2019/8/16 16:56
     */
    @Transactional
    public int updateIsCloseByWaiTingSignTime(List<Long> ids){
        logger.info("开始修改完结状态");
        if(!CollectionUtils.isEmpty(ids)) {
            logger.info("修改完结状态: " + ids.size() + "条");
            return repository.updateByWhere(PredicateBuilder.conjunction()
                    .and(() -> Q.id.in(ids))
                    .get(), it -> it.set(Q.isClose, true));
        }
        return 0;
    }

    /**
     * 功能描述: 关闭定时任务
     *
     * @param logisticCode 物流编码
     * @param logisticNumber 物流单号
     *
     * @return
     * @auther Kien
     * @date 2019/12/10 20:11
     */
    @Transactional
    public JSONObject closeLogisticOverTask(String logisticCode, String logisticNumber) {
        logger.info("进入关闭定时任务");
        JSONObject jsonObject = new JSONObject();
        if(base.parametersIsBlank(logisticCode, logisticNumber)){
            logger.info("关闭定时任务时参数为空");
            jsonObject.put("status", IntergenixConstant.JsonEnmu.PARAM_NULL.getStatus());
            return jsonObject;
        }
        int i = repository.updateByWhere(PredicateBuilder.conjunction()
                .and(() -> Q.logisticCode.eq(logisticCode))
                .and(() -> Q.logisticNumber.eq(logisticNumber))
                .get(), it -> it.set(Q.isClose, true));
        if(i != 0) {
            logger.info("关闭定时任务成功");
        }
        jsonObject.put("status", IntergenixConstant.JsonEnmu.SUCCESS.getStatus());
        return jsonObject;
    }
}
